local class = require('java-core.utils.class')
local log = require('java-core.utils.log2')
local system = require('java-core.utils.system')

---@class java-core.Tar
---@field source string
---@field dest string
local Tar = class()

---@class java-core.TarOpts
---@field source string Path to tar file (supports .tar, .tar.gz, .tgz, .tar.xz)
---@field dest string Destination directory

---@param opts java-core.TarOpts
function Tar:_init(opts)
	self.source = opts.source
	self.dest = opts.dest
end

---@private
---Check if tar supports --force-local
---@param tar_cmd string
---@return boolean
function Tar:tar_supports_force_local(tar_cmd)
	local ok, out = pcall(vim.fn.system, { tar_cmd, '--help' })
	if not ok then
		return false
	end
	return out:match('%-%-force%-local') ~= nil
end

---Extract tar file using tar
---@return boolean|nil # true on success, nil on failure
---@return string|nil # Error message if failed
function Tar:extract()
	local tar_cmd = vim.fn.executable('gtar') == 1 and 'gtar' or 'tar'
	log.debug('tar extracting:', self.source, 'to', self.dest)
	log.debug('Using tar binary:', tar_cmd)

	local cmd
	if system.get_os() == 'win' then
		-- Windows: convert backslashes to forward slashes (tar accepts them)
		local source = self.source:gsub('\\', '/')
		local dest = self.dest:gsub('\\', '/')
		cmd = string.format(
			'%s --no-same-owner %s -xf "%s" -C "%s"',
			tar_cmd,
			self:tar_supports_force_local(tar_cmd) and '--force-local' or '',
			source,
			dest
		)
	else
		-- Unix: use shellescape
		cmd = string.format(
			'%s --no-same-owner -xf %s -C %s',
			tar_cmd,
			vim.fn.shellescape(self.source),
			vim.fn.shellescape(self.dest)
		)
	end
	log.debug('tar command:', cmd)

	local result = vim.fn.system(cmd)
	local exit_code = vim.v.shell_error

	if exit_code ~= 0 then
		log.error('tar extraction failed:', exit_code, result)
		return nil, string.format('tar failed (exit %d): %s', exit_code, result)
	end

	log.debug('tar extraction completed')
	return true, nil
end

return Tar
